<?php
class DB{
	static $MODEL=array();
	/**
	*	Вывод списка таблиц базы
	*	
	*	@return array 
	*/
	static function showTables() {
		$sql='SHOW TABLES';
		return exec_sql2list( $sql );		
	}
	
	
	/** 
	* getTableProp
	*
	* сборка и получение свойств таблицы
	*
	* @param $tableName имя таблицы
	* @param $reinit обновление кэша модели
	* @return array or null
	*/
	static function getTableProp( $tableName, $reinit=false ) {
		if ( isset(self::$MODEL[$tableName]) && !$reinit ) return self::$MODEL[$tableName];
		
		//echo 'reinit!';
		$MODEL[$tableName] = null;

		$query="SELECT COLUMN_NAME,COLUMN_DEFAULT,IS_NULLABLE,DATA_TYPE,COLUMN_TYPE,COLUMN_COMMENT
		FROM 
			information_schema.columns
		WHERE 
			table_name = '".$tableName."' 
			AND table_schema = '".DB_NAME."'";
		$res = exec_sql2array( $query ); //myPrint( $res, 'getTableProp '.$tableName);
		/**/
		if( count($res)>0 ) {
			foreach( $res as $arr ) self::$MODEL[ $tableName ][ $arr[ 'COLUMN_NAME' ] ]=$arr;
			return self::$MODEL[$tableName];
		} else {
			return null;
		}
		
	}
	/** 
	* 	createRequestArr
	*
	*	сборка массива полей-значений из $_REQUEST согласно таблицам $useTables 
	*	@param array $useTables - список таблиц в которых ищутся поля запроса
	*	@return array 
	*/
	static function createRequestArr( array $useTables ) {
		$requestArr = array();
		foreach( $useTables as $tableName){
			$fielsArr = self::getTableProp( $tableName);
			foreach( $fielsArr as $fieldName=>$propArr ){
				if( isset($_REQUEST[ $fieldName ]) ){
					if(!is_scalar($_REQUEST[ $fieldName ]))
						throw new Exception ( __METHOD__.': $_REQUEST["'.$fieldName.'"] shoud be scalar not '.gettype($_REQUEST[ $fieldName ]) ); 
					//if( strlen( $_REQUEST[ $fieldName ] )>0 )
						$requestArr[ $tableName ][ $fieldName ] = Form::magic_stripslashes( $_REQUEST[ $fieldName ] );	
				} 			
			}
		}
		return $requestArr;
	}
	
	/** 
	* 	checkMandatory
	*
	*	Элементарная проверка на заполненность обязательных полей таблицы IS_NULLABLE=NO
	*	возвращает пустой массив или массив не заполненных обязательных полей,
	*	где ключ - имя поля, значение - комментарий поля в таблице
	*	@param string $tableName
	*	@param array $valuesArr
	*/
	static function checkMandatory( $tableName, $valuesArr ) {
		$result = array();
		$fielsArr = self::getTableProp( $tableName);
		foreach( $fielsArr as $fieldName=>$propArr ){
			if( $propArr['IS_NULLABLE']=='NO'){
				if(!array_key_exists($fieldName, $valuesArr) || strlen($valuesArr[$fieldName])<1)
					$result[$fieldName]=$propArr['COLUMN_COMMENT'];
			} 
		}
		return $result;
	}
	
	/** 
	*	arrToSet
	*
	*	generating SET string from array : ( ..., ..., ... ) 
	*/
	static function arrToSet($arr) {
		$values='';
		foreach( $arr as $field=>$value){
			if(is_string($value)) $value = $value;
			$values.="'".$value."', ";
		}
		$values = rtrim( $values,', ');
		
		return '('.$values.')';
	}
	
	/**
	*	arrToInsertSet
	*
	*	generating Insert string from array : ( ..., ..., ... ) VALUES ( ..., ..., ... ) 
	*	prefix	"expression:" for SQL expressions 
	*/
	static function arrToInsertSet($arr) {
		$fields=''; $values='';
		foreach( $arr as $field=>$value){
			$fields.=$field.', ';
			if(is_string($value)) $value = $value;
			if( strstr($value, 'expression:') ) {
				$value=str_replace( 'expression:', '', $value);
				$values.=$value.", "; 
			} else $values.="'".$value."', ";
		}
		$fields = rtrim( $fields,', '); 
		$values = rtrim( $values,', ');
		
		return '('.$fields.') VALUES ('.$values.')';
	}
	
	/** 
	*	arrToUpdateSet
	*
	*	generating Update string from array : ...='...',  ...='...', ...='...' 
	*	prefix	"expression:" for SQL expressions 
	*/
	static function arrToUpdateSet($arr) {
		$setStr='';
		foreach( $arr as $field=>$value){
			if(is_string($value)) $value = $value;
			if( strstr($value, 'expression:') ) {
				$value=str_replace( 'expression:', '', $value);
				$setStr.= $field." = ".$value.", ";
			} else	$setStr.= $field." = '".$value."', ";
		}
		$setStr = rtrim( $setStr,', '); 
		return $setStr;
	}
	
	/**
	*	getInsertQueryArr
	*
	*	окончательная сборка запроса Insert через arrToInsertSet,
	*	вернет массив с элементами 'id' и 'query' :
	*
	*	@param $tableName - имя таблицы, 
	*	@param $valuesArr - массив полей-значений, 
	*/
	static public function getInsertQueryArr( $tableName, $valuesArr){
		return array(
			'id'=>!empty($idFieldName) ? $valuesArr[ $idFieldName ] : ( isset($valuesArr[ $tableName.'_ID' ]) ? $valuesArr[ $tableName.'_ID' ] :null ),
			'query'=>'INSERT INTO '.$tableName.' '.self::arrToInsertSet($valuesArr)
		);	
	}
	
	/**
	*	insertTableArray
	*
	*	базовый INSERT, сборка запроса в getInsertQueryArr и выполнение : 
	*	если не передано $idFieldName , значит генерится не будет, предполагается, что оно уже есть в массиве
	*
	*	@param $tableName - имя таблицы, 
	*	@param $valuesArr - массив полей-значений, 
	*/
	static public function insertTableArray( $tableName, $valuesArr ){
		$queryArr = self::getInsertQueryArr( $tableName, $valuesArr );
		$query = $queryArr['query']; //echo $query.'<br>';
		
		exec_sql( $query);
	}
	
	/**  
	*	updateTableArrayWhere
	*
	*	базовый UPDATE, сборка запроса через arrToUpdateSet и выполнение : 
	*	@param имя таблицы, 
	*	@param массив полей-значений, 
	*	@param строка WHERE (без самого where)
	*/	
	static public function updateTableArrayWhere( $tableName, $valuesArr, $whereString ){
		$query = 'UPDATE  '.$tableName.' SET '.self::arrToUpdateSet($valuesArr);
		if( !empty($whereString) ) $query.=' WHERE '.$whereString;
		else throw new Exception( __METHOD__.' missing condition WHERE in UPDATE query: '.$query ); 
		//echo $query;
		exec_sql( $query );
		return  array( 'input'=>$valuesArr, 'query'=>$query  );
	}
}
?>